home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / shell / ncd-0.000 / ncd-0 / ncd-0.9.8 / nodes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-06  |  11.2 KB  |  533 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <sys/stat.h>
  6.  
  7. #include "ncd.h"
  8.  
  9. /*************************************************************************/
  10. /* basename must end with a slash. If {baseNode} is NULL, it is also
  11.    created based on {baseName} */
  12.  
  13. DirNode *readDirsInNodes(char *baseName, DirNode * baseNode)
  14. {
  15.     char fullName[PATH_MAX];
  16.     DIR *dir;
  17.     int testproc;
  18.     DirNode *lastUp;
  19.     static int i;
  20.     static DirNode *newNode;
  21.     static struct dirent *entry;
  22.     static char linkName[PATH_MAX];
  23.     static struct stat entryStat;
  24.  
  25.     if ((_verbose)&&(!_cursesOn))
  26.         fprintf(stderr, "%s\n", baseName);
  27.  
  28.     if (baseNode == NULL) {
  29.         baseNode = malloc(sizeof(DirNode));
  30.         if (baseNode == NULL) {
  31.             cleanUp();
  32.             fprintf(stderr, "error: no memory\n");
  33.             exit(1);
  34.         }
  35.         baseNode->left = baseNode->right = baseNode->up =
  36.             baseNode->down = NULL;
  37.         baseNode->lname = NULL;
  38.         baseNode->name = getDirName(baseName);
  39.     }
  40.     dir = opendir(baseName);
  41.     testproc = (strcmp(baseName, "/") == 0);
  42.     lastUp = NULL;
  43.     while ((entry = readdir(dir)) != NULL) {
  44.         if ((strcmp(entry->d_name, ".") != 0) &&
  45.             (strcmp(entry->d_name, "..") != 0) /* &&
  46.             ((!testproc) || (strcmp(entry->d_name, "proc") != 0)) */) {
  47.             sprintf(fullName, "%s%s", baseName, entry->d_name);
  48.             i = stat(fullName, &entryStat);
  49.             if (S_ISDIR(entryStat.st_mode)) {
  50.                 newNode = malloc(sizeof(DirNode));
  51.                 if (newNode == NULL) {
  52.                     cleanUp();
  53.                     fprintf(stderr, "error: no memory\n");
  54.                     exit(1);
  55.                 }
  56.                 newNode->name = strdup(entry->d_name);
  57.                 if (newNode->name == NULL) {
  58.                     cleanUp();
  59.                     fprintf(stderr, "error: no memory\n");
  60.                     exit(1);
  61.                 }
  62.                 newNode->left = baseNode;
  63.                 newNode->right = NULL;
  64.                 newNode->up = lastUp;
  65.                 newNode->down = NULL;
  66.                 if (baseNode->right == NULL)
  67.                     baseNode->right = newNode;
  68.                 if (lastUp != NULL)
  69.                     lastUp->down = newNode;
  70.                 lastUp = newNode;
  71.                 i = lstat(fullName, &entryStat);
  72.                 if (S_ISLNK(entryStat.st_mode)) {
  73.                     i = readlink(fullName, linkName, PATH_MAX);
  74.                     linkName[(i < 0) ? 0 : i] = '\0';
  75.                     if ((_verbose)&&(!_cursesOn))
  76.                         fprintf(stderr, "%s -> %s\n", fullName, linkName);
  77.                     newNode->lname = strdup(linkName);
  78.                     if (newNode->lname == NULL) {
  79.                         cleanUp();
  80.                         fprintf(stderr, "error: no memory\n");
  81.                         exit(1);
  82.                     }
  83.                 }
  84.                 else {    /* not a link */
  85.                     newNode->lname = NULL;
  86.                     addSlash(fullName);
  87.                     if ((!testproc) || (strcmp(entry->d_name, "proc") != 0))
  88.                         readDirsInNodes(fullName, newNode);
  89.                 }
  90.             }
  91.         }
  92.     }
  93.     closedir(dir);
  94.  
  95.     return baseNode;
  96. }
  97.  
  98. /*************************************************************************/
  99.  
  100. DirNode *readNodesFromFile(char *fname)
  101. {
  102.     char line[PATH_MAX + 3];
  103.     DirNode *node, *first, *oldNode;
  104.     FILE *f;
  105.     size_t len;
  106.  
  107.     f = fopen(fname, "r");
  108.     if (f == NULL) {
  109.         if ((_verbose)&&(!_cursesOn))
  110.             fprintf(stderr, "warning: can't read file %s\n", fname);
  111.         return NULL;
  112.     }
  113.     node = first = oldNode = NULL;
  114.     while (fgets(line, PATH_MAX + 3, f) != NULL) {
  115.         len = strlen(line);
  116.         if (len < 2)
  117.             continue;
  118.         line[len - 1] = 0;    /* strip \n */
  119.         switch (line[0]) {
  120.         case '>':    /* son */
  121.             node = malloc(sizeof(DirNode));
  122.             if (node == NULL) {
  123.                 cleanUp();
  124.                 fprintf(stderr, "error: no memory\n");
  125.                 exit(1);
  126.             }
  127.             node->name = strdup(line + 2);
  128.             if (node->name == NULL) {
  129.                 cleanUp();
  130.                 fprintf(stderr, "error: no memory\n");
  131.                 exit(1);
  132.             }
  133.             node->lname = NULL;
  134.             node->left = oldNode;
  135.             node->right = node->up = node->down = NULL;
  136.             if (oldNode == NULL)
  137.                 first = node;
  138.             else
  139.                 oldNode->right = node;
  140.  
  141.             oldNode = node;
  142.             break;
  143.         case '<':    /* one up */
  144.             if ((oldNode == NULL)) {
  145.                 cleanUp();
  146.                 fprintf(stderr, "error: invalid file %s\n", fname);
  147.                 exit(1);
  148.             }
  149.             oldNode = oldNode->left;
  150.             break;
  151.         case 'V':    /* brother */
  152.             if ((oldNode == NULL) || (oldNode->left == NULL)) {
  153.                 cleanUp();
  154.                 fprintf(stderr, "error: invalid file %s\n", fname);
  155.                 exit(1);
  156.             }
  157.             node = malloc(sizeof(DirNode));
  158.             if (node == NULL) {
  159.                 cleanUp();
  160.                 fprintf(stderr, "error: no memory\n");
  161.                 exit(1);
  162.             }
  163.             node->name = strdup(line + 2);
  164.             if (node->name == NULL) {
  165.                 cleanUp();
  166.                 fprintf(stderr, "error: no memory\n");
  167.                 exit(1);
  168.             }
  169.             node->lname = NULL;
  170.             node->left = oldNode->left;
  171.             node->up = oldNode;
  172.             node->down = node->right = NULL;
  173.             oldNode->down = node;
  174.             oldNode = node;
  175.             break;
  176.         case 'L':
  177.             if (oldNode == NULL) {
  178.                 cleanUp();
  179.                 fprintf(stderr, "error: invalid file %s\n", fname);
  180.                 exit(1);
  181.             }
  182.             oldNode->lname = strdup(line + 2);
  183.             if (oldNode->lname == NULL) {
  184.                 cleanUp();
  185.                 fprintf(stderr, "error: no memory\n");
  186.                 exit(1);
  187.             }
  188.             break;
  189.         default:
  190.             cleanUp();
  191.             fprintf(stderr, "error: invalid file %s\n", fname);
  192.             exit(1);
  193.         }
  194.     }
  195.     if ((oldNode != NULL) && (oldNode->left != NULL) && ((_verbose)&&(!_cursesOn)))
  196.         fprintf(stderr, "warning: possibly truncated file %s\n", fname);
  197.  
  198.     fclose(f);
  199.     return first;
  200. }
  201.  
  202. /*************************************************************************/
  203.  
  204. void writeSubNodeTreeToFile(FILE * f, DirNode * node)
  205. {
  206.     fprintf(f, "%s\n", node->name);
  207.     if (node->lname != NULL)
  208.         fprintf(f, "L %s\n", node->lname);
  209.     if (node->right) {
  210.         fprintf(f, "> ");
  211.         writeSubNodeTreeToFile(f, node->right);
  212.     }
  213.     if (node->down) {
  214.         fprintf(f, "V ");
  215.         writeSubNodeTreeToFile(f, node->down);
  216.     }
  217.     else
  218.         fprintf(f, "< \n");
  219. }
  220.  
  221. /*************************************************************************/
  222.  
  223. void writeNodesToFile(char *fname, DirNode * baseNode)
  224. {
  225.     FILE *f;
  226.  
  227.     f = fopen(fname, "w");
  228.     if (f == NULL) {
  229.         if ((_verbose)&&(!_cursesOn))
  230.             fprintf(stderr, "warning: can't write file %s\n", fname);
  231.         return;
  232.     }
  233.     if (baseNode != NULL) {
  234.         fprintf(f, "> ");
  235.         writeSubNodeTreeToFile(f, baseNode);
  236.     }
  237.     fclose(f);
  238. }
  239.  
  240. /*************************************************************************/
  241.  
  242. void delNodesFromMemory(DirNode * baseNode)
  243. {
  244.     if (baseNode == NULL)
  245.         return;
  246.  
  247.     delNodesFromMemory(baseNode->right);
  248.     delNodesFromMemory(baseNode->down);
  249.     if (baseNode->name)
  250.         free(baseNode->name);
  251.     if (baseNode->lname)
  252.         free(baseNode->lname);
  253. }
  254.  
  255. /*************************************************************************/
  256. /* showlink==0 no   ==1 ->link  ==-1 @ */
  257.  
  258. char *getNodeName(DirNode * node, int showlink)
  259. {
  260.     static char s[PATH_MAX * 2];
  261.  
  262.     s[0] = '\0';
  263.     strcat(s, " ");
  264.     strcat(s, node->name);
  265.     if (node->lname != NULL) {
  266.         if (showlink==1) {
  267.             strcat(s, " -> ");
  268.             strcat(s, node->lname);
  269.             strcat(s, "/");
  270.         }
  271.         else if (showlink==-1)
  272.             strcat(s, "@");
  273.     }
  274.     strcat(s, " ");
  275.     return s;
  276. }
  277.  
  278. /*************************************************************************/
  279. /* withlink==0 no   ==1 ->link  ==-1 @ */
  280.  
  281. char *getNodeFullPath(DirNode * node, int withlink, int relative, DirNode * relNode, int use_xroot )
  282. {
  283.     char s[PATH_MAX * 2];
  284.     char *sn;
  285.  
  286.     sn = getNodeName(node, withlink);
  287.     if ((relative) || (node->left != NULL)) {
  288.         strcpy(s, sn + 1);
  289.         strcpy(sn, s);
  290.         sn[strlen(sn) - 1] = '\0';
  291.     }
  292.     else
  293.         sn[0] = 0;
  294.  
  295.     s[0] = 0;
  296.  
  297.     while (node->left != NULL) {
  298.         if ((relative) && (node == relNode))
  299.             break;
  300.  
  301.         node = node->left;
  302.  
  303.         if ((relative) || (node->left != NULL)) {
  304.             strcpy(s, node->name);
  305.             addSlash(s);
  306.             strcat(s, sn);
  307.             strcpy(sn, s);
  308.         }
  309.     }
  310.     if (!relative) {
  311.         if (use_xroot)
  312.             strcpy(s, _xroot);
  313.         else
  314.             strcpy(s, _root);
  315.         addSlash(s);
  316.         strcat(s, sn);
  317.         strcpy(sn, s);
  318.     }
  319.  
  320.     return sn;
  321. }
  322.  
  323. /*************************************************************************/
  324.  
  325. int numerateNodeTree(DirNode * rootNode, int x, int y)
  326. {
  327.     int len;
  328.  
  329.     if (rootNode == NULL)
  330.         return y;
  331.  
  332.     rootNode->x = x;
  333.     rootNode->y = y;
  334.     len = strlen(rootNode->name);
  335.     if (rootNode->lname != NULL)
  336.         len++;
  337.  
  338.     if (rootNode->right)
  339.         y = numerateNodeTree(rootNode->right, x + len + 2 + 3, y);
  340.     if (rootNode->down)
  341.         y = numerateNodeTree(rootNode->down, x, y + 1);
  342.  
  343.     return y;
  344. }
  345.  
  346. /*************************************************************************/
  347.  
  348. DirNode *followLink(DirNode * rootNode, DirNode * node, int isLast )
  349. {
  350.     DirNode *dn;
  351.     char s[PATH_MAX * 2];
  352.     char * ss, * st;
  353.  
  354.     if (node == NULL)
  355.         return NULL;
  356.     if (node->lname == NULL)
  357.         return NULL;
  358.     _nLinks++;
  359.     if (_nLinks>MAX_LINKS)
  360.         return NULL;
  361.  
  362.     if (node->lname[0]=='/') {  /* absolute */
  363.         stripSlash(_root);
  364.         if (strstr(node->lname,_root)==node->lname) {
  365.             strcpy(s,_xroot);
  366.             strcat(s,(node->lname)+strlen(_root));
  367.         }
  368.         else
  369.             strcpy(s,node->lname);
  370.         addSlash(_root);
  371.     }
  372.     else {  /* relative */
  373.         strcpy(s,getNodeFullPath(node, 0, 0, NULL, 1));
  374.         addSlash(s);
  375.         strcat(s,"../");
  376.         strcat(s,node->lname);
  377.     }
  378.     while (1) {
  379.         compactAbsDir(s);
  380.         dn = locatePathOrSo(s,&ss);
  381.  
  382.         if (dn->lname!=NULL) {
  383.             if ((isLast)&&((ss[0]=='\0')||((ss[0]=='/')&&(ss[1]=='\0'))))
  384.                 return dn;
  385.             dn = followLink(rootNode, dn, 0);
  386.             if (dn==NULL) 
  387.                 return NULL;
  388.             else  {
  389.                 st = getNodeFullPath(dn, 0, 0, NULL, 1);
  390.                 addSlash(st);
  391.                 strcat(st,ss);
  392.                 strcpy(s,st);
  393.             }
  394.         }
  395.         else {
  396.             if ((ss[0]=='\0')||((ss[0]=='/')&&(ss[1]=='\0'))) 
  397.                 return dn;
  398.             else 
  399.                 return NULL;
  400.         }
  401.     }
  402.  
  403.     return NULL;
  404. }
  405.  
  406. /*************************************************************************/
  407.  
  408. DirNode *getNodeFollowLink(DirNode * rootNode, DirNode * node)
  409. {
  410.     DirNode *dn;
  411.  
  412.     if (node == NULL)
  413.         return NULL;
  414.     if (node->lname == NULL)
  415.         return node;
  416.         
  417.     _nLinks = 0;
  418.     dn = followLink(rootNode, node, 1);
  419.     
  420.     if (dn==NULL) 
  421.         return node;
  422.     else 
  423.         return dn;
  424. }
  425.  
  426. /*************************************************************************/
  427.  
  428. char *getTreeLine(DirNode * node, int lineart, int marksel)
  429. {
  430. #define MAXLEN (PATH_MAX*5)        /* (PATH_MAX/2)*6+PATH_MAX + some */
  431.  
  432.     static char line[MAXLEN];
  433.     char tline[MAXLEN];
  434.     size_t len, i;
  435.  
  436.     line[0] = '\0';
  437.  
  438.     if (node == NULL)
  439.         return NULL;
  440.  
  441.     do {
  442.         tline[0] = '\0';
  443.         if (node->left != NULL) {
  444.             if (node->up == NULL) {
  445.                 if (node->down == NULL) {
  446.                     if (lineart) {
  447.                         tline[0] = tline[1] = tline[2] = __ACS_HL;
  448.                         tline[3] = 0;
  449.  
  450.                     }
  451.                     else
  452.                         strcpy(tline, "---");
  453.                 }
  454.                 else {
  455.                     if (lineart) {
  456.                         tline[0] = tline[2] = __ACS_HL;
  457.                         tline[1] = __ACS_TT;
  458.                         tline[3] = 0;
  459.                     }
  460.                     else
  461.                         strcpy(tline, "-+-");
  462.                 }
  463.             }
  464.             else {
  465.                 if (node->down == NULL) {
  466.                     if (lineart) {
  467.                         tline[0] = ' ';
  468.                         tline[1] = __ACS_LLC;
  469.                         tline[2] = __ACS_HL;
  470.                         tline[3] = 0;
  471.                     }
  472.                     else
  473.                         strcpy(tline, " `-");
  474.                 }
  475.                 else {
  476.                     if (lineart) {
  477.                         tline[0] = ' ';
  478.                         tline[1] = __ACS_LT;
  479.                         tline[2] = __ACS_HL;
  480.                         tline[3] = 0;
  481.                     }
  482.                     else
  483.                         strcpy(tline, " |-");
  484.                 }
  485.             }
  486.         }
  487.         if (_curNode == node) {
  488.             strcat(tline, " ");
  489.             tline[strlen(tline) - 1] = __SEL_ON;
  490.         }
  491.         strcat(tline, getNodeName(node, (_showlink?1:-1)));
  492.         if (_curNode == node) {
  493.             strcat(tline, " ");
  494.             tline[strlen(tline) - 1] = __SEL_OFF;
  495.         }
  496.         strcat(tline, line);
  497.         strcpy(line, tline);
  498.  
  499.         if (node->up != NULL) {
  500.             node = node->left;
  501.             break;
  502.         }
  503.  
  504.         node = node->left;
  505.     } while (node != NULL);
  506.  
  507.     while (node != NULL) {
  508.         tline[0] = '\0';
  509.         if (node->left != NULL) {
  510.             if (node->down != NULL) {
  511.                 if (lineart) {
  512.                     strcat(tline, "   ");
  513.                     tline[strlen(tline) - 2] = __ACS_VL;
  514.                 }
  515.                 else
  516.                     strcat(tline, " | ");
  517.             }
  518.             else
  519.                 strcat(tline, "   ");
  520.         }
  521.         len = strlen(node->name) + ((node->lname != NULL) ? 1 : 0) + 2;
  522.         for (i = 0; i < len; i++)
  523.             strcat(tline, " ");
  524.         strcat(tline, line);
  525.         strcpy(line, tline);
  526.         node = node->left;
  527.     }
  528.  
  529.     return line;
  530. }
  531.  
  532. /*************************************************************************/
  533.